
/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.waveprotocol.wave.model.id {
import org.waveprotocol.wave.model.util.StringBuilder;
import org.goverla.collections.ArrayList;

public class URIEncoderDecoder {
	
	private static var NOT_ESCAPED:ArrayList= new ArrayList();
	
	private function init():void {
		var str:String =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:@!$&'()*+,;=-._~";
		var a_str:Array = str.split("");
		for(var c:int = 0; c < a_str.length; c++) {
			NOT_ESCAPED.addItem(a_str[c]);		
		}
	}
	
	private var percentEncoder:PercentEncoderDecoder;
	
	public function URIEncoderDecoder(percentEncoder:PercentEncoderDecoder) {
		this.percentEncoder = percentEncoder;
		init();
	}
	
	public function encode(decodedValue:String):String {
		var out:StringBuilder= new StringBuilder();
		
		for (var i:int= 0; i < decodedValue.length;) {
			var c:String= decodedValue.charAt(i);
			if (NOT_ESCAPED.contains(c)) {
				out.append(c);
				i++;
			} else {
				var j:int= i;
				// convert to external encoding before hex conversion
				do {
					i++;
				} while (i < decodedValue.length && !NOT_ESCAPED.contains((decodedValue.charAt(i))));
				
				out.append(percentEncoder.encode(decodedValue.substring(j, i)));
			}
		}
		return out.toString();
	}
	
	public function decode(encodedValue:String):String  {
		return percentEncoder.decode(encodedValue);
	}
}
}